package cn.iocoder.yudao.module.reading.dal.mysql.plan;

import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.reading.dal.dataobject.plan.PlanDailyTaskDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.time.LocalDate;
import java.util.List;

/**
 * 计划每日任务 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface PlanDailyTaskMapper extends BaseMapperX<PlanDailyTaskDO> {

    /**
     * 根据计划ID和日期查询任务列表
     *
     * @param planId   计划ID
     * @param taskDate 任务日期
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectByPlanIdAndDate(Long planId, LocalDate taskDate) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getTaskDate, taskDate)
                .orderByAsc(PlanDailyTaskDO::getSortOrder));
    }

    /**
     * 根据用户ID和日期查询任务列表
     *
     * @param userId   用户ID
     * @param taskDate 任务日期
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectByUserIdAndDate(Long userId, LocalDate taskDate) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getUserId, userId)
                .eq(PlanDailyTaskDO::getTaskDate, taskDate)
                .orderByAsc(PlanDailyTaskDO::getPlanId)
                .orderByAsc(PlanDailyTaskDO::getSortOrder));
    }

    /**
     * 根据计划ID查询所有任务
     *
     * @param planId 计划ID
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectByPlanId(Long planId) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .orderByAsc(PlanDailyTaskDO::getTaskDate)
                .orderByAsc(PlanDailyTaskDO::getSortOrder));
    }

    /**
     * 根据计划ID和绘本ID查询任务
     *
     * @param planId 计划ID
     * @param bookId 绘本ID
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectByPlanIdAndBookId(Long planId, Long bookId) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getBookId, bookId)
                .orderByAsc(PlanDailyTaskDO::getTaskDate));
    }

    /**
     * 根据计划ID、绘本ID和日期查询当天的未完成任务
     *
     * @param planId 计划ID
     * @param bookId 绘本ID
     * @param taskDate 任务日期
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectTodayUncompletedTasks(Long planId, Long bookId, LocalDate taskDate) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getBookId, bookId)
                .eq(PlanDailyTaskDO::getTaskDate, taskDate)
                .eq(PlanDailyTaskDO::getIsCompleted, false)
                .orderByAsc(PlanDailyTaskDO::getSortOrder));
    }

    /**
     * 根据计划ID和绘本ID查询所有未完成任务
     *
     * @param planId 计划ID
     * @param bookId 绘本ID
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectUncompletedTasksByBookId(Long planId, Long bookId) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getBookId, bookId)
                .eq(PlanDailyTaskDO::getIsCompleted, false)
                .orderByAsc(PlanDailyTaskDO::getTaskDate)
                .orderByAsc(PlanDailyTaskDO::getSortOrder));
    }

    /**
     * 根据计划ID删除任务
     *
     * @param planId 计划ID
     * @return 删除数量
     */
    default int deleteByPlanId(Long planId) {
        return delete(PlanDailyTaskDO::getPlanId, planId);
    }

    /**
     * 统计计划已完成任务数
     *
     * @param planId 计划ID
     * @return 已完成任务数
     */
    default Long countCompletedByPlanId(Long planId) {
        return selectCount(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getIsCompleted, true));
    }

    /**
     * 统计计划已完成的唯一绘本数量
     * 每本绘本只计算一次，无论有多少个任务（新学+复习）
     *
     * @param planId 计划ID
     * @return 已完成的唯一绘本数量
     */
    @Select("SELECT COUNT(DISTINCT book_id) FROM plan_daily_tasks " +
            "WHERE plan_id = #{planId} AND is_completed = 1 AND deleted = 0")
    Long countCompletedBooksByPlanId(Long planId);

    /**
     * 查询指定绘本的所有任务状态（用于调试验证）
     *
     * @param planId 计划ID
     * @param bookId 绘本ID
     * @return 任务列表
     */
    default List<PlanDailyTaskDO> selectTaskStatusByBookId(Long planId, Long bookId) {
        return selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getBookId, bookId)
                .orderByAsc(PlanDailyTaskDO::getTaskDate));
    }

    /**
     * 获取计划已完成任务的最大天数
     *
     * @param planId 计划ID
     * @return 最大天数，如果没有已完成任务则返回0
     */
    default Integer getMaxCompletedDayNumber(Long planId) {
        List<PlanDailyTaskDO> completedTasks = selectList(new LambdaQueryWrapperX<PlanDailyTaskDO>()
                .eq(PlanDailyTaskDO::getPlanId, planId)
                .eq(PlanDailyTaskDO::getIsCompleted, true)
                .orderByDesc(PlanDailyTaskDO::getDayNumber)
                .last("LIMIT 1"));

        return completedTasks.isEmpty() ? 0 : completedTasks.get(0).getDayNumber();
    }

}
